package com.manong.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.manong.domain.*;
import com.manong.exception.BusinessExp;
import com.manong.mapper.*;
import com.manong.query.OrderQueryObject;
import com.manong.service.IOrderService;
import com.manong.vo.OrderStoreVo;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class OrderServiceImpl implements IOrderService {
    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private OrderStoreMapper orderStoreMapper;
    @Autowired
    private GoodsWarehouseMapper goodsWarehouseMapper;
    @Autowired
    private GoodsMapper goodsMapper;
    @Autowired
    private WarehouseMapper warehouseMapper;
    @Autowired
    private StoreMapper storeMapper;
    @Autowired
    private GoodsStoreMapper goodsStoreMapper;

    @Override
    public PageInfo query(OrderQueryObject queryObject) {
        if (queryObject.getPageSize() == -1) {
            List<Order> order = orderMapper.selectForList(queryObject);
            return new PageInfo(order);
        } else {
            //PageHelper进行分页操作
            //告诉PageHelper 当前页是多少 每页显示数据
            PageHelper.startPage(queryObject.getPageNum(), queryObject.getPageSize());
            //调用分页方法
            List<Order> order = orderMapper.selectForList(queryObject);
            return new PageInfo(order);
        }
    }

    @Override
    public void delete(Integer id) {
        if (id == null) {
            throw new BusinessExp("参数不能为空");
        }
        int count = orderMapper.deleteByPrimaryKey(id);
        orderStoreMapper.deleteByOrderId(id);
        // count 影响行数， 如果count == 0 表示删除失败
        if (count == 0) {
            throw new BusinessExp("删除失败");
        }
    }

    @Override
    public void saveOrUpdate(OrderStoreVo order) {
        if (order == null) {
            throw new BusinessExp("非法操作");
        }
        if (order.getOrder().getOrder_id() == null) {
            this.save(order);
        } else {
            this.update(order);
        }
    }

    @Transactional
    @Override
    public void save(OrderStoreVo order) {
        // 1、保存订单主表
        Order orderInfo = order.getOrder();
        orderInfo.setCreation_time(new Date()); // 设置创建时间
        orderMapper.insert(orderInfo); // 插入后需要获取生成的ID

        // 2. 获取生成的订单ID
        Integer orderId = orderInfo.getOrder_id();
        if (orderId == null) {
            throw new BusinessExp("订单创建失败");
        }
        // 3、保存关联商品（优化数据结构）
        List<OrderStore> orderStores = order.getOrderStores();
        ; // 建议改成单层list
        if (orderStores != null) {
            orderStores.forEach(store -> {
                store.setOrder_id(orderId); //
            });
            orderStoreMapper.batchInsert(orderStores); // 批量插入
        }
    }

    @Override
    public void update(OrderStoreVo order) {
        // vo对象中获取role对象
        Order orderInfo = order.getOrder();
        orderMapper.updateByPrimaryKey(orderInfo);
    }

    @Override
    public Order get(Integer id) {
        if (id == null) {
            throw new BusinessExp("id不能为空");
        }
        Order order = orderMapper.selectOrderWithGoods(id);
        if (order == null) {
            throw new BusinessExp("非法操作");
        }
        return order;
    }

    @Override
    public void confirmOrder(OrderStoreVo order) {
        // 1. 参数校验
        if (order == null || order.getOrder() == null || order.getOrder().getOrder_id() == null) {
            throw new BusinessExp("订单参数异常");
        }

        // 2. 构建待更新的订单对象
        Order orderToUpdate = new Order();
        orderToUpdate.setOrder_id(order.getOrder().getOrder_id());
        orderToUpdate.setCourier(order.getOrder().getCourier());   // 设置订单ID
        orderToUpdate.setOrder_status("INDELIVERY");               // 更新状态
        orderToUpdate.setConfirm_time(new Date());                 // 设置确认时间

        // 3. 调用Mapper执行更新
        int rows = orderMapper.updateOrderStatus(orderToUpdate);
        if (rows == 0) {
            throw new BusinessExp("订单不存在或更新失败");
        }
    }

    @Transactional
    @Override
    public void confirmWarehouse(OrderStoreVo order) {
// 1. 参数校验
        if (order == null || order.getOrder() == null || CollectionUtils.isEmpty(order.getOrderStores())) {
            throw new BusinessExp("参数不合法");
        }
        Integer warehouseId = order.getOrder().getOrigin_id();  // 仓库ID
        if (warehouseId == null) {
            throw new BusinessExp("仓库ID不能为空");
        }


        // 2. 构建待更新的订单对象
        Order orderToUpdate = new Order();
        orderToUpdate.setOrder_id(order.getOrder().getOrder_id());  // 设置订单ID
        orderToUpdate.setOrder_status("FINISH");               // 更新状态
        orderToUpdate.setFinish_time(new Date());

        // 3. 调用Mapper执行更新
        int rows = orderMapper.finishOrderStatus(orderToUpdate);
        if (rows == 0) {
            throw new BusinessExp("订单不存在或更新失败");
        }

        // 2. 构建库存操作列表
        List<GoodsWarehouse> operations = order.getOrderStores().stream()
                .map(item -> new GoodsWarehouse(
                        warehouseId,
                        item.getStore_id().longValue(),  // 假设store_id是Integer，转为Long
                        item.getStore_num(),
                        generateBatchNo()
                ))
                .collect(Collectors.toList());

        // 3. 批量插入或更新库存
        goodsWarehouseMapper.batchInsertOrUpdate(operations);

        BigDecimal totalOccupancy = calculateTotalOccupancy(order.getOrderStores());

        // 3. 更新仓库已用空间
        warehouseMapper.increaseUsedSpace(warehouseId, totalOccupancy);
    }

    @Transactional
    @Override
    public void confirmStore(OrderStoreVo order) {
        // 1. 参数校验
        if (order == null || order.getOrder() == null || CollectionUtils.isEmpty(order.getOrderStores())) {
            throw new BusinessExp("参数不合法");
        }
        Integer storeId = order.getOrder().getDestination_id();  // 门面ID
        Integer warehouseId = order.getOrder().getOrigin_id();   // 仓库ID
        if (storeId == null || warehouseId == null) {
            throw new BusinessExp("门面ID或仓库ID不能为空");
        }

        // 2. 更新订单状态为已完成
        Order orderToUpdate = new Order();
        orderToUpdate.setOrder_id(order.getOrder().getOrder_id());
        orderToUpdate.setOrder_status("FINISH");
        orderToUpdate.setFinish_time(new Date());
        int rows = orderMapper.finishOrderStatus(orderToUpdate);
        if (rows == 0) throw new BusinessExp("订单更新失败");

        // 3. 从仓库扣除库存（需校验库存充足）
        deductFromWarehouse(warehouseId, order.getOrderStores());

        // 4. 增加门面库存
        addToStore(storeId, order.getOrderStores());

        // 5. 更新仓库和门面的已用容量
        updateSpaceUsage(warehouseId, storeId, order.getOrderStores());
    }

    /**
     * 查询每日订单数量
     *
     * @return
     */
    @Override
    public List<Map<String, Object>> getDailyOrderCount() {
        return orderMapper.getDailyOrderCount();
    }

    @Override
    public int getTotalOrderCount() {
        return orderMapper.selectAll().size();
    }

    @Override
    public List<Map<String, Object>> getDailyOrderCountByOriginId(Integer originId) {
        return orderMapper.getDailyOrderCountByOriginId(originId);
    }

    @Override
    public List<Map<String, Object>> getOrderStatusCountByOriginId(Integer originId) {
        return orderMapper.getOrderStatusCountByOriginId(originId);
    }

    @Override
    public List<Map<String, Object>> getDailyOrderCountByOriginIdAndOrderType(Integer originId) {
        return orderMapper.getDailyOrderCountByOriginIdAndOrderType(originId);
    }

    @Override
    public List<Map<String, Object>> getOrderStatusCountByOriginIdAndOrderType(Integer originId) {
        return orderMapper.getOrderStatusCountByOriginIdAndOrderType(originId);
    }

    // 生成批次号（示例）
    private String generateBatchNo() {
        return "BATCH-" + System.currentTimeMillis();
    }
    private BigDecimal calculateTotalOccupancy(List<OrderStore> orderStores) {
        return orderStores.stream()
                .map(item -> {
                    // 查询商品单位占用量
                    BigDecimal quality = goodsMapper.getQualityByGoodsId(Long.valueOf(item.getStore_id()));
                    if (quality == null) {
                        throw new BusinessExp("商品ID " + item.getStore_id() + " 未配置质量");
                    }
                    // 计算占用量：质量 * 数量
                    return quality.multiply(BigDecimal.valueOf(item.getStore_num()));
                })
                .reduce(BigDecimal.ZERO, BigDecimal::add);
    }

    private void deductFromWarehouse(Integer warehouseId, List<OrderStore> items) {
        // 检查库存是否充足
        items.forEach(item -> {
            Integer currentStock = goodsWarehouseMapper.getStockQuantity(
                    warehouseId,
                    item.getStore_id().longValue()
            );
            if (currentStock == null || currentStock < item.getStore_num()) {
                throw new BusinessExp("商品ID " + item.getStore_id() + " 库存不足");
            }
        });

        // 批量扣除
        List<GoodsWarehouse> deductions = items.stream()
                .map(item -> new GoodsWarehouse(
                        warehouseId,
                        item.getStore_id().longValue(),
                        -item.getStore_num(),  // 负数表示扣除
                        "OUT-" + System.currentTimeMillis() // 关联订单号
                ))
                .collect(Collectors.toList());

        goodsWarehouseMapper.batchUpdateQuantity(deductions);
    }

    private void updateSpaceUsage(Integer warehouseId, Integer storeId, List<OrderStore> items) {
        // 计算总占用量（质量×数量）
        BigDecimal totalOccupancy = calculateTotalOccupancy(items);

        // 仓库减少已用空间（出库）
        warehouseMapper.decreaseUsedSpace(warehouseId, totalOccupancy);

        // 门面增加已用空间（入库）
        storeMapper.increaseUsedSpace(storeId, totalOccupancy);
    }

    private void addToStore(Integer storeId, List<OrderStore> items) {
        List<GoodsStore> additions = items.stream()
                .map(item -> new GoodsStore(
                        storeId,
                        item.getStore_id().longValue(),
                        item.getStore_num(),
                        "IN-" + System.currentTimeMillis()
                ))
                .collect(Collectors.toList());

        goodsStoreMapper.batchInsertOrUpdate(additions);
    }
}
